/*
 * Portions Copyright  2000-2009 Sun Microsystems, Inc. All Rights
 * Reserved.  Use is subject to license terms.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt).
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions.
 */
package gov.nist.siplite;

import gov.nist.siplite.stack.Transaction;
import gov.nist.siplite.stack.ClientTransaction;
import gov.nist.siplite.stack.ServerTransaction;

/**
 * This interface represents the application view to a SIP stack
 * therefore defines the application's communication channel to the SIP stack.
 * This is patterened on the JAIN-SIP SIP-Listener ( but it is not identical
 * to it).
 *
 * @see SipProvider
 * @see RequestEvent
 * @see ResponseEvent
 * @see TimeoutEvent
 *
 * @version 1.1
 */
public interface SipListener  {
    
    /**
     * Processes a Request received on a SipProvider upon which this SipListener
     * is registered.
     * <p>
     * <b>Handling Requests:</b><br>
     * When the application receives a RequestEvent from the SipProvider the
     * RequestEvent may or may not belong to an existing dialog of the
     * application.
     * The application can be determine if the RequestEvent belongs to an
     * existing dialog by checking the server transaction of the RequestEvent.
     * <ul>
     * <li>If the server transaction equals <code>null</code> the
     * RequestEvent does
     * not belong to an existing dialog and the application must determine how
     * to handle the RequestEvent. If the application decides to forward the
     * Request statelessly no transactional support is required and it
     * can simply
     * pass the Request of the RequestEvent as an argument to the
     * {@link SipProvider#sendRequest(Request)} method. However if the
     * application determines to respond to a Request statefully it must request
     * a new server transaction from the
     * {@link SipProvider#getNewServerTransaction(Request)} method and use this
     * server transaction to send the Response based on the content of
     * the Request.
     * If the SipProvider throws TransactionAlreadyExistsException when the
     * application requests a new server transaction to handle a Request the
     * current RequestEvent is a retransmission of the initial request
     * from which
     * the application hadn't requested a server transaction to handle it, i.e.
     * this exception handles the race condition of an application
     * informing the
     * SipProvider that it will handle a Request and the receipt of a
     * retransmission of the Request from the network to the SipProvider.
     * <li>If the server transaction <b>does NOT</b> equal
     *  <code>null</code> the
     * application determines its action to the RequestEvent based on
     * the content of the Request information.
     * </ul>
     * <p>
     * <b>User Agent Server (UAS) Behaviour:</b><br>
     * A UAS application decides whether to accept the an invitation from a
     * UAC. The UAS application can accept the invitation by sending a 2xx
     * response to the UAC, a 2xx response to an INVITE transaction establishes
     * a session. For 2xx responses, the processing is done by the UAS
     * application, to guarantee the three way handshake of an INVITE
     * transaction. This specification defines a utility thats enables the
     * SipProvider to handle the 2XX processing for an INVITE transaction, see
     * the {@link SipStack#isRetransmissionFilterActive()} method. If the
     * invitation is not accepted, a 3xx, 4xx, 5xx or 6xx response is sent by
     * the application, depending on the reason for
     * the rejection. Alternatively before sending a final response, the UAS
     * can also send provisional responses (1xx) to advise the UAC of progress
     * in contacting the called user. A UAS that receives a CANCEL request for
     * an INVITE, but has not yet sent a final response, would "stop ringing"
     * and then respond to the INVITE with a specific 487 Error response.
     * <p>
     * <b>General Proxy behaviour:</b><br>
     * In some circumstances, a proxy application MAY forward requests using
     * stateful transports without being transaction stateful,
     * i.e. using the {@link SipProvider#sendRequest(Request)} method,
     * but using TCP as a transport.  For example, a proxy application MAY
     * forward a request from one TCP connection to another transaction
     * statelessly as long as it places enough information in the message to be
     * able to forward the response down the same connection the request arrived
     * on. This is the responsibility of the application and not the
     * SipProvider.
     * Requests forwarded between different types of transports where the
     * proxy application takes an active role in ensuring reliable delivery on
     * one of the transports must be forwarded using the stateful send methods
     * on the SipProvider.
     * <p>
     * <b>Stateful Proxies:</b><br>
     * A stateful proxy MUST create a new server transaction for each new
     * request received, either automatically generated by the SipProvider,
     * if the request matches an existing dialog or by the an
     * application call on the SipProvider if it decides to respond to the
     * request statefully. The proxy application determines where to
     * route the request, choosing one or more next-hop locations. An outgoing
     * request for each next-hop location is processed by its own associated
     * client transaction.  The proxy application collects the responses from
     * the client transactions and uses them to send responses to the server
     * transaction. When an application receives a CANCEL request that matches
     * a server transaction, a stateful proxy cancels any pending client
     * transactions associated with a response context. A stateful proxy
     * responds to the CANCEL rather than simply forwarding a response it would
     * receive from a downstream element.
     * <p>
     * For all new Requests, including any with unknown methods, an element
     * intending to stateful proxy the Request determines the target(s) of the
     * request. A stateful proxy MAY process the targets in any order.
     * A stateful proxy must have a mechanism to maintain the target set as
     * responses are received and associate the responses to each forwarded
     * request with the original request. For each target, the proxy forwards
     * the request following these steps:
     * <ul>
     * <li>Make a copy of the received request.
     * <li>Update the Request-URI.
     * <li>Update the Max-Forwards header.
     * <li>Optionally add a Record-route header.
     * <li>Optionally add additional headers.
     * <li>Postprocess routing information.
     * <li>Determine the next-hop address, port, and transport.
     * <li>Add a Via header.
     * <li>Add a Content-Length header if necessary.
     * <li>Forward the new request using the
     * {@link ClientTransaction#sendRequest()} method.
     * <li>Process all responses recieved on the
     * {@link SipListener#processResponse(ResponseEvent)} method.
     * <li>NOT generate 100 (Trying) responses to non-INVITE requests.
     * </ul>
     * <p>
     * A stateful proxy MAY transition to stateless operation at any time
     * during the processing of a request, as long as it did nothing that
     * would prevent it from being stateless initially i.e. forking or
     * generation of a 100 response. When performing such a transition, any
     * state already stored is simply discarded.
     * <p>
     * <b>Forking Requests:</b><br>
     * A stateful proxy application MAY choose to "fork" a request, routing it
     * to multiple destinations. Any request that is forwarded to more than
     * one location MUST be forwarded using the stateful send methods on the
     * SipProvider.
     * <p>
     * <b>Stateless Proxies:</b><br>
     * As a stateless proxy does not have any notion of a transaction, or of
     * the response context used to describe stateful proxy behavior,
     * <code>requestEvent.getServerTransaction() == null;</code>
     * always return <var>true</var>. The transaction layer of the SipProvider
     * implementation is by-passed.  For all requests including any with
     * unknown methods, an application intending to stateless proxy the request
     * MUST:
     * <ul>
     * <li>Validate the request.
     * <li>Preprocess routing information.
     * <li>Determine a single target(s) for the request.
     * <li>Forward the request to the target using the
     * {@link SipProvider#sendRequest(Request)} method.
     * <li>NOT perform special processing for CANCEL requests.
     * </ul>
     *
     * @since v1.1
     * @param requestEvent - requestEvent fired from the SipProvider to
     * the SipListener representing a Request received from the network.
     */
    public void processRequest(RequestEvent requestEvent);
    
    /**
     * Processes a Response received on a SipProvider upon which this
     * SipListener is registered.
     * <p>
     * <b>Handling Responses:</b><br>
     * When the application receives a ResponseEvent from the SipProvider the
     * ResponseEvent may or may not correlate to an existing Request of the
     * application. The application can be determine if the
     * ResponseEvent belongs
     * to an existing Request by checking the client transaction of the
     * ResponseEvent.
     * <ul>
     * <li>If the the client transaction equals <code>null</code> the
     * ResponseEvent does not belong to an existing Request and the Response is
     * considered stray, i.e. stray response can be identitied, if
     * <code>responseEvent.getClientTransaction() == null;</code>. Handling of
     * these "stray" responses is dependent on the application i.e. a
     * proxy will forward them statelessly using the
     * {@link SipProvider#sendResponse(Response)} method, while a User
     * Agent will discard them.
     * <li>If the client transaction <b>does NOT</b> equal
     * <code>null</code> the
     * application determines it action to the ResponseEvent based on the
     * content of the Response information.
     * </ul>
     * <p>
     * <b>User Agent Client (UAC) behaviour:</b><br>
     * After possibly receiving one or more provisional responses (1xx) to a
     * Request, the UAC will get one or more 2xx responses or one non-2xx final
     * response. Because of the protracted amount of time it can take
     * to receive
     * final responses to an INVITE, the reliability mechanisms for INVITE
     * transactions differ from those of other requests.
     * A UAC needs to send an ACK for every final Response it receives, however
     * the procedure for sending the ACK depends on the type of Response. For
     * final responses between 300 and 699, the ACK processing is done by the
     * transaction layer i.e. handled by the implementation. For 2xx
     * responses, the
     * ACK processing is done by the UAC application, to guarantee the
     * three way
     * handshake of an INVITE transaction. This specification defines a utility
     * thats enables the SipProvider to handle the ACK processing for an INVITE
     * transaction, see the {@link
     * SipStack#isRetransmissionFilterActive()} method.
     * <br>
     * A 2xx response to an INVITE establishes a session, and it also
     * creates a dialog between the UAC that issued the INVITE and the UAS
     * that generated the 2xx response. Therefore, when multiple 2xx responses
     * are received from different remote User Agents, i.e. the INVITE forked,
     * each 2xx establishes a different dialog and all these dialogs
     * are part of
     * the same call. If an INVITE client transaction returns a {@link
     * TimeoutEvent}
     * rather than a response the UAC acts as if a 408 (Request Timeout)
     * response had been received from the UAS.
     * <p>
     * <b>Stateful Proxies:</b><br>
     * A proxy application that handles a response statefully must do the
     * following processing:
     * <ul>
     * <li>Find the appropriate response context.
     * <li>Remove the topmost Via header.
     * <li>Add the response to the response context.
     * <li>Check to determine if this response should be forwarded immediately.
     * <li>When necessary, choose the best final response from the
     * response context. If no final response has been forwarded after every
     * client transaction associated with the response context has been
     * terminated, the proxy must choose and forward the "best" response
     * from those it has seen so far.
     * </ul>
     * <p>
     * Additionally the following processing MUST be performed on each response
     * that is forwarded.
     * <ul>
     * <li>Aggregate authorization header values if necessary.
     * <li>Optionally rewrite Record-Route header values.
     * <li>Forward the response using the
     * {@link ServerTransaction#sendResponse(Response)} method.
     * <li>Generate any necessary CANCEL requests.
     * </ul>
     * <p>
     * <b>Stateless Proxies:</b><br>
     * As a stateless proxy does not have any notion of transactions, or of
     * the response context used to describe stateful proxy behavior,
     * <code>responseEvent.getClientTransaction == null;</code>
     * always return <var>true</var>. Response processing does not apply, the
     * transaction layer of the SipProvider implementation is by-passed. An
     * application intending to stateless proxy the Response MUST:
     * <ul>
     * <li>Inspect the sent-by value in the first Via header.
     * <li>If that address matches the proxy, the proxy MUST remove that header
     * from the response.
     * <li>Forward the resulting response to the location indicated in the
     * next Via header using the
     * {@link SipProvider#sendResponse(Response)} method.
     * </ul>
     *
     * @since v1.1
     * @param responseEvent - the responseEvent fired from the SipProvider to
     * the SipListener representing a Response received from the network.
     */
    public void processResponse(ResponseEvent responseEvent);
    
    /**
     * Processes a retransmit or expiration Timeout of an underlying
     * {@link Transaction} handled by this SipListener. This Event notifies the
     * application that a retransmission or transaction Timer expired in the
     * SipProvider's transaction state machine. The TimeoutEvent encapsulates
     * the specific timeout type and the transaction identifier either client
     * or server upon which the timeout occured. The type of Timeout can by
     * determined by:
     * <code>timeoutType = timeoutEvent.getTimeout().getValue();</code>
     *
     * @param timeoutEvent - the timeoutEvent received indicating either the
     * message retransmit or transaction timed out.
     */
    public void processTimeout(TimeoutEvent timeoutEvent);
    
}

